package com.lucan.tracking.plugin.visitor

import com.lucan.tracking.annotations.Configuration
import com.lucan.tracking.plugin.visitor.anno.ConfigurationAnnoVisitor
import com.lucan.tracking.plugin.visitor.method.ConfigurationMethodVisitor
import com.lucan.tracking.plugin.visitor.method.TrackMethodVisitor
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.MethodVisitor
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Type

/**
 * @author qihailong
 * @date 2018/7/23 上午11:35
 * @description TODO
 */
class TrackClassVisitor extends ClassVisitor {

    String mBaseUrl = ""
    boolean isConfiguration = false
    String mClassName = ""

    TrackClassVisitor(int api, ClassVisitor cv) {
        super(api, cv)
    }

    @Override
    void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
        super.visit(version, access, name, signature, superName, interfaces)
        mClassName = name
    }

    @Override
    MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions)
        if (isConfiguration) {
            return new ConfigurationMethodVisitor(Opcodes.ASM5, mv, access, name, desc, mBaseUrl, mClassName)
        }
        return new TrackMethodVisitor(Opcodes.ASM5, mv, access, name, desc)
    }

    @Override
    AnnotationVisitor visitAnnotation(String desc, boolean visible) {
        AnnotationVisitor annotationVisitor = super.visitAnnotation(desc, visible)
        if (Type.getDescriptor(Configuration.class) == desc) {
            isConfiguration = true
            return new ConfigurationAnnoVisitor(api, annotationVisitor, desc, { Map<String, String> map ->
                mBaseUrl = map?.get(ConfigurationAnnoVisitor.KEY_BASE_URL, "") ?: ""
            })
        }
        return annotationVisitor
    }
}
